﻿using System;
using System.Text;
using System.Runtime.InteropServices;

namespace PWFrameWork
{
    public static class WinApi
    {
        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All =                       0x001F0FFF,
            Terminate =                 0x00000001,
            CreateThread =              0x00000002,
            VmOperation =               0x00000008,
            VmRead =                    0x00000010,
            VmWrite =                   0x00000020,
            DupHandle =                 0x00000040,
            SetInformation =            0x00000200,
            QueryInformation =          0x00000400,
            Synchronize =               0x00100000
        }

        [Flags]
        public enum AllocationType
        {
            Commit =                    0x1000,
            Reserve =                   0x2000,
            Decommit =                  0x4000,
            Release =                   0x8000,
            Reset =                     0x80000,
            Physical =                  0x400000,
            TopDown =                   0x100000,
            WriteWatch =                0x200000,
            LargePages =                0x20000000
        }

        [Flags]
        public enum MemoryProtection
        {
            Execute =                   0x10,
            ExecuteRead =               0x20,
            ExecuteReadWrite =          0x40,
            ExecuteWriteCopy =          0x80,
            NoAccess =                  0x01,
            ReadOnly =                  0x02,
            ReadWrite =                 0x04,
            WriteCopy =                 0x08,
            GuardModifierflag =         0x100,
            NoCacheModifierflag =       0x200,
            WriteCombineModifierflag =  0x400
        }

        [Flags]
        public enum FreeType
        {
            Decommit = 0x4000,
            Release = 0x8000,
        }

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll")]
        public static extern Int32 ReadProcessMemory(
            IntPtr hProcess,
            Int32 lpBaseAddress,
            [In, Out] Byte[] buffer,
            Int32 size,
            out Int32 lpNumberOfBytesRead
            );

        [DllImport("kernel32.dll")]
        public static extern bool WriteProcessMemory(
            IntPtr hProcess,
            Int32 lpBaseAddress,
            [In, Out] Byte[] buffer,
            Int32 nSize,
            out Int32 lpNumberOfBytesWritten);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
           Int32 dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
           Int32 dwSize, FreeType dwFreeType);

        [DllImport("kernel32.dll")]
        public static extern IntPtr CreateRemoteThread(IntPtr hProcess,
           IntPtr lpThreadAttributes, int dwStackSize, IntPtr lpStartAddress,
           IntPtr lpParameter, int dwCreationFlags, out IntPtr lpThreadId);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, Int32 nMaxCount);

        public static string GetWindowClass(IntPtr handle)
        {
            var rtnStr = new StringBuilder(128);
            GetClassName(handle, rtnStr, 128);
            return rtnStr.ToString();
        }
    }
}
